/*
 * Created on Feb 11, 2005
 * Created by dfhuynh
 */
package edu.mit.simile.longwell.query.project;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;

import edu.mit.simile.longwell.Profile;

/**
 * @author dfhuynh
 */
public class IntegerProjector extends PropertyProjector {
	protected class IntegerPropertyProjection 
		extends LongValueProjection 
		implements IIntegerProjection {
		
		public IntegerPropertyProjection(Set objects) {
			super(
				IntegerProjector.this.m_profile, 
				IntegerProjector.this.m_property, 
				IntegerProjector.this.m_forward, 
				IntegerProjector.this.m_locale, 
				objects);
		}
		
		/* (non-Javadoc)
		 * @see edu.mit.simile.longwell.query.project.PropertyProjection#internalGetObjects(java.lang.Object)
		 */
		protected Set internalGetObjects(Object value) {
			Set		allObjects = getObjects();
			Set 	objects = new HashSet();
			int		v = value != null ? ((Integer) value).intValue() : Integer.MIN_VALUE;
			
			Iterator i = allObjects.iterator();
			while (i.hasNext()) {
				Resource r = (Resource) i.next();
				if (v == getInteger(r)) {
					objects.add(r);
				}
			}
			return objects;
		}
		
		/* (non-Javadoc)
		 * @see edu.mit.simile.longwell.query.project.PropertyProjection#nodeToValue(com.hp.hpl.jena.rdf.model.RDFNode)
		 */
		protected Object nodeToValue(RDFNode node) {
			return nodeToInteger(node);
		}
		
		/* (non-Javadoc)
		 * @see edu.mit.simile.longwell.query.IIntegerProjection#getInteger(com.hp.hpl.jena.rdf.model.Resource)
		 */
		public int getInteger(Resource object) {
			Integer i = (Integer) getValue(object);
			return i == null ? Integer.MIN_VALUE : i.intValue();
		}
		
		/* (non-Javadoc)
		 * @see edu.mit.simile.longwell.query.project.IIntegerProjection#getMin()
		 */
		public int getMin() {
			long l = internalGetMin();
			return l < Integer.MIN_VALUE ? Integer.MIN_VALUE : (int) l;
		}
		
		/* (non-Javadoc)
		 * @see edu.mit.simile.longwell.query.project.IIntegerProjection#getMax()
		 */
		public int getMax() {
			long l = internalGetMax();
			return l > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) l;
		}
		
		/* (non-Javadoc)
		 * @see edu.mit.simile.longwell.query.project.IIntegerProjection#countObjects(int, int)
		 */
		public int countObjects(int fromInclusive, int toExclusive) {
			return internalCountObjects(fromInclusive, toExclusive);
		}
		
		/* (non-Javadoc)
		 * @see edu.mit.simile.longwell.query.project.IIntegerProjection#getObjects(int, int)
		 */
		public Set getObjects(int fromInclusive, int toExclusive) {
			return internalGetObjects(fromInclusive, toExclusive);
		}

		/* (non-Javadoc)
		 * @see edu.mit.simile.longwell.query.project.LongValueProjection#valueToLong(java.lang.Object)
		 */
		protected long valueToLong(Object v) {
			return v != null ? ((Integer) v).intValue() : Long.MIN_VALUE;
		}

		/* (non-Javadoc)
		 * @see edu.mit.simile.longwell.query.project.ProjectionBase#internalGetObjectToValueMap()
		 */
		protected Map internalGetObjectToValueMap() {
			Map m = new HashMap();
			fillObjectToValueMap(m);
			return m;
		}
	}

	/**
	 * @param profile
	 * @param parameter
	 */
	public IntegerProjector(Profile profile, String parameter, String locale) {
		super(profile, parameter, locale);
	}
	
	/* (non-Javadoc)
	 * @see edu.mit.simile.longwell.query.project.PropertyProjector#isEfficientForRootProjection()
	 */
	public boolean isEfficientForRootProjection() {
		return false;
	}
	
	/* (non-Javadoc)
	 * @see edu.mit.simile.longwell.query.project.PropertyProjector#internalProject()
	 */
	protected IProjection internalProject() {
		return new IntegerPropertyProjection(null);
	}

	/* (non-Javadoc)
	 * @see edu.mit.simile.longwell.query.project.ProjectorBase#internalProject(java.util.Set)
	 */
	protected IProjection internalProject(Set objects) {
		return new IntegerPropertyProjection(objects);
	}

	final protected Integer nodeToInteger(RDFNode node) {
		if (node instanceof Literal) {
			try {
				int i = Integer.parseInt(((Literal) node).getString());
			
				return new Integer(i);
			} catch (NumberFormatException e) {
			}
		}
		return null;
	}
	
}
